/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import java.util.ArrayList;
import pojo.Message;
import pojo.Property;
import pojo.QueryInfo;

/**
 *
 * @author HoangLiem
 */
public class ExecUpdateQuery {

    public static boolean validateAndExecQuery(String databaseName, String query, Message message) {
        boolean result = true;
        try {
            String tableName = "";
            String originalSet = "";//bien nay luu chinh xac thanh phan set
            String tempQuery = query;
            tempQuery = ExecQuery.trimMoreSpace(tempQuery);

            String[] s = tempQuery.split(" ");
            if (s.length < 5) {// phai it nhất co 5 đoan trong cau update
                message.setMessage("Query not enough components");
                return false;
            }
            //kiem tra ton tai update, la doan có chi so 0 trong s
            if (!s[0].toLowerCase().trim().equals("update")) {
                message.setMessage("Error at 'update' component");
                return false;
            }

            //Kiem tra ton  tại ten bang, s[1]
            ArrayList<String> tableNames = ExecTableXML.getNamesOfTable(databaseName);
            if (!ExecXML.isExistedString(tableNames, s[1].toLowerCase().trim())) {
                message.setMessage("Table '" + s[1] + "' does not exists");
                return false;
            } else {
                tableName = s[1].toLowerCase().trim();
            }
            //kiem tra có thành phần set, s[2]
            if (!s[2].toLowerCase().trim().equals("set")) {
                message.setMessage("Error at 'set' component");
                return false;
            } else {
                originalSet = s[2];
            }
            //kiem tra thanh phan WHERE
            //luc nay ta ko xài chuoi tempQuery mà su dung chuoi query goc de lay thanh phan sau set.
            String afterSet = query.substring(query.indexOf(originalSet));
            afterSet = afterSet.replace(originalSet, "").trim();

            // split theo where, neu co 2 phan thi moi dung.
            ArrayList<String> splitWhere = ExecQuery.splitWhere(afterSet);
            if (splitWhere.size() != 2) {
                message.setMessage("Error, much 'WHERE' components");
                return false;
            }

            String set = splitWhere.get(0).trim();
            String where = splitWhere.get(1).trim();
            QueryInfo updateData = new QueryInfo();
            ArrayList<QueryInfo> conditionList = new ArrayList<QueryInfo>();
            //Xu ly thanh phan set
            if (set.equals("")) {
                message.setMessage("Error at 'SET' components");
                return false;
            }
            if (where.equals("")) {
                message.setMessage("Error at 'SET' components");
                return false;
            }
            //split theo dau phay, luu y dau phẩy ko nằm trong dấu ' ' 
            ArrayList<String> splitComma = ExecQuery.splitComma(set);
            if (splitComma.isEmpty()) {
                message.setMessage("Error at 'SET' components");
                return false;
            } else {
                ArrayList<String> propertyUpdateNames = new ArrayList<String>();
                ArrayList<String> propertyUpdateData = new ArrayList<String>();
                for (int i = 0; i < splitComma.size(); i++) {
                    String comma = splitComma.get(i).trim();
                    if (comma.equals("") || comma.length() < 3) {
                        message.setMessage("Error at set");
                        return false;
                    } else {
                        ArrayList<String> splitEqual = ExecQuery.splitEqual(comma);
                        if (splitEqual.size() > 0) {//chia theo dấu =
                            if (splitEqual.size() > 2) {
                                message.setMessage("Error at SET, much '='");
                                return false;
                            } else {
                                //kiem tra ton tai thuoc tinh, data
                                String field = splitEqual.get(0).trim();
                                String data = splitEqual.get(1).trim();
                                if (field.equals("") || data.equals("")) {
                                    message.setMessage("Error at SET, field name or data empty");
                                    return false;
                                }
                                ArrayList<String> fieldNames = ExecTableXML.getAllFieldsFromTable(databaseName, tableName);
                                if (!ExecXML.isExistedString(fieldNames, field)) {
                                    message.setMessage("Error at SET, field name not exist");
                                    return false;
                                }
                                Property pro = ExecTableXML.getFieldOfTable(databaseName, tableName, field);
                                if (pro == null) {
                                    message.setMessage("Error when get info of '" + field + "'");
                                    return false;
                                }
                                if (pro.getType().equalsIgnoreCase("string")) {
                                    //kiem tra la chuoi
                                    if (data.length() >= 2) {
                                        if (data.charAt(0) == '\'' && data.charAt(data.length() - 1) == '\'') {
                                            data = ExecQuery.trimCharsFirstEnd(data);
                                            if (!data.contains("'")) {
                                                if (data.length() > pro.getLength()) {
                                                    message.setMessage("Error data of SET components at '" + data + "', length data greater length in field");
                                                    return false;
                                                }
                                                propertyUpdateNames.add(field);
                                                propertyUpdateData.add(data);
                                            } else {
                                                message.setMessage("Error data of SET components ' at '" + data + "'");
                                                return false;
                                            }

                                        } else {
                                            message.setMessage("Error data of SET components ' at '" + data + "'");
                                            return false;
                                        }
                                    } else {
                                        message.setMessage("Error data of SET components at '" + data + "'");
                                        return false;
                                    }
                                } else {
                                    //kiem tra la so nguyen
                                    if (pro.getType().equalsIgnoreCase("integer")) {
                                        if (ExecXML.isInteger(data)) {
                                            propertyUpdateNames.add(field);
                                            propertyUpdateData.add(data);
                                        } else {
                                            message.setMessage("Error data of SET components at '" + data + "'");
                                            return false;
                                        }
                                    } else {//kiem tra so thuc
                                        if (ExecXML.isReal(data)) {
                                            propertyUpdateNames.add(field);
                                            propertyUpdateData.add(data);
                                        } else {
                                            message.setMessage("Error data of SET components at '" + data + "'");
                                            return false;
                                        }
                                    }
                                }

                            }
                        } else {
                            message.setMessage("Error at SET component");
                            return false;
                        }
                    }
                }
                //Add thong tin vao updateData
                updateData.setPropertyNames(propertyUpdateNames);
                updateData.setPropertyData(propertyUpdateData);
            }


            //Xu ly thanh phan where
            //mot cau truy van OR co the tach thanh 2 cau truy van con
            ArrayList<String> splitOr = ExecQuery.splitOr(where);
            if (splitOr.size() > 0) {
                for (int i = 0; i < splitOr.size(); i++) {
                    String or = splitOr.get(i).trim();
                    if (or.equals("")) {
                        message.setMessage("Error at codition");
                        return false;
                    } else {
                        ArrayList<String> splitAnd = ExecQuery.splitAnd(or);
                        if (splitAnd.size() > 0) {
                            ArrayList<String> propertyNames = new ArrayList<String>();
                            ArrayList<String> propertyData = new ArrayList<String>();
                            for (int j = 0; j < splitAnd.size(); j++) {
                                String and = splitAnd.get(j).trim();
                                if (and.equals("") || and.length() < 3) {
                                    message.setMessage("Error at codition");
                                    return false;
                                } else {
                                    ArrayList<String> splitEqual = ExecQuery.splitEqual(and);
                                    if (splitEqual.size() > 0) {//chia theo dấu =
                                        if (splitEqual.size() > 2) {
                                            message.setMessage("Error at condition, much '='");
                                            return false;
                                        } else {
                                            //kiem tra ton tai thuoc tinh, data
                                            String field = splitEqual.get(0).trim();
                                            String data = splitEqual.get(1).trim();
                                            if (field.equals("") || data.equals("")) {
                                                message.setMessage("Error at condition, field name or data empty");
                                                return false;
                                            }
                                            ArrayList<String> fieldNames = ExecTableXML.getAllFieldsFromTable(databaseName, tableName);
                                            if (!ExecXML.isExistedString(fieldNames, field)) {
                                                message.setMessage("Error at condition, field name not exist");
                                                return false;
                                            }
                                            Property pro = ExecTableXML.getFieldOfTable(databaseName, tableName, field);
                                            if (pro == null) {
                                                message.setMessage("Error when get info of '" + field + "'");
                                                return false;
                                            }
                                            if (pro.getType().equalsIgnoreCase("string")) {
                                                //kiem tra la chuoi
                                                if (data.length() >= 2) {
                                                    if (data.charAt(0) == '\'' && data.charAt(data.length() - 1) == '\'') {
                                                        data = ExecQuery.trimCharsFirstEnd(data);
                                                        if (!data.contains("'")) {
                                                            if (data.length() > pro.getLength()) {
                                                                message.setMessage("Error data at '" + data + "', length data greater length in field");
                                                                return false;
                                                            }
                                                            propertyNames.add(field);
                                                            propertyData.add(data);
                                                        } else {
                                                            message.setMessage("Error data ' at '" + data + "'");
                                                            return false;
                                                        }

                                                    } else {
                                                        message.setMessage("Error data ' at '" + data + "'");
                                                        return false;
                                                    }
                                                } else {
                                                    message.setMessage("Error data at '" + data + "'");
                                                    return false;
                                                }
                                            } else {
                                                //kiem tra la so nguyen
                                                if (pro.getType().equalsIgnoreCase("integer")) {
                                                    if (ExecXML.isInteger(data)) {
                                                        propertyNames.add(field);
                                                        propertyData.add(data);
                                                    } else {
                                                        message.setMessage("Error data at '" + data + "'");
                                                        return false;
                                                    }
                                                } else {//kiem tra so thuc
                                                    if (ExecXML.isReal(data)) {
                                                        propertyNames.add(field);
                                                        propertyData.add(data);
                                                    } else {
                                                        message.setMessage("Error data at '" + data + "'");
                                                        return false;
                                                    }
                                                }
                                            }

                                        }
                                    } else {
                                        message.setMessage("Error at codition");
                                        return false;
                                    }
                                }
                            }
                            //Add thong tin vao queryInfo
                            QueryInfo queryInfo = new QueryInfo(propertyNames, propertyData);
                            conditionList.add(queryInfo);
                        } else {
                            message.setMessage("Error at codition");
                            return false;
                        }
                    }
                }
            }
            //Bat dau update, QueryInfo updateData, ArrayList<QueryInfo> conditionList
            int updated = 0;
            if (conditionList != null && !conditionList.isEmpty()) {
                for (int i = 0; i < conditionList.size(); i++) {
                    QueryInfo queryCondition = conditionList.get(i);
                    updated = updated + ExecRowXML.updateRow(databaseName, tableName, queryCondition, updateData);
                }
            } else {
                message.setMessage("Error condition empty");
                result = false;
            }
            message.setMessage(updated+" rows updated");

        } catch (Exception ex) {
            message.setMessage("Error when update");
            result = false;
        }
        return result;
    }   
}
